#include <malloc.h>
#include <stdint.h>
#include "include/core.h"
#include "include/task.h"
#include "include/simul.h"
#include "qdebug.h"
#include "include/cluster.h"



core_list *dequeue_core_list(Core *core, Cluster *global)
{
    core_list *pos;
    core_list *head = global->cores;

    for(pos = head->next; pos != head; pos = pos->next){
        if(pos->core == core){
            del_core_list(pos->pre, pos->next);
            delete pos;

            return pos;
        }
    }

    return nullptr;
}

void enqueue_core_list(core_list *changed, Cluster *global)
{
    core_list *pos;
    core_list *head = global->cores;

    for(pos = head->next; pos != head; pos = pos->next){
        if(pos->core->scheduled_prio < changed->core->scheduled_prio){
            add_core_list(changed, pos->pre, pos);
            return;
        }
    }

    add_core_list_tail(changed, head);
}

Task *GetScheduledTask(Core *core)
{
    int scheduled = core->task_scheduled;
    int task_num;
    if(scheduled == PrioMin)
        return nullptr;

    for(task_num=0;taskSets[task_num].task_id!=0;task_num++)
       {

        }
    for(int i = 0; i < task_num; ++i){
        if(taskSets[i].task_id == scheduled)
            return &taskSets[i];
    }

    return nullptr;
}

void enqueue_utilization(Core *core, core_list *h)
{
    if(core == nullptr)
         return;
    core_list *New = new core_list;
    New->core = core;
    core_list *pos;
    core_list *head = h;

    for(pos = head->next; pos != head; pos = pos->next){
        if(pos->core->utilization > core->utilization){
            add_core_list(New, pos->pre, pos);
            return;
        }
    }
    add_core_list_tail(New, head);
}

void dequeue_utilization(Core *core, core_list *h)
{
    if(core == nullptr)
        return;
    core_list *pos;
    core_list *head = h;

    for(pos = head->next; pos != head; pos = pos->next){
        if(pos->core->core_id == core->core_id){
            del_core_list(pos->pre, pos->next);
            delete pos;

            return;
        }
    }
}



void initCore(int core_id, double rate, double prob, int time, int cluster)
{
    qDebug()<<"get "<<core_id<<"!"<<endl;
    qDebug()<<"core_id "<<core_id<<"!"
              <<"core_rate "<<rate<<"!"
                <<"core_recovery_time "<<time<<"!"
           <<endl;
    local_core = &cores[core_id-1];

    local_core->core_id = core_id;
    local_core->task_scheduled = -1;
    local_core->task_sched_type = -1;
    local_core->rate = rate;
    local_core->scheduled_prio = PrioMin;
    local_core->ready_queue = init_task_list_head();
    local_core->suspend_queue = init_task_list_head();
    local_core->utilization = 0;
    local_core->isFailed = false;
    local_core->ceiling_prior=PrioMin;
    enqueue_utilization(local_core, core_utilization);
}

void initLocalCore(int core_id, double rate, double prob, int time, int cluster)
{
    qDebug()<<"get "<<core_id<<"!"<<endl;
    qDebug()<<"core_id "<<core_id<<"!"
              <<"core_rate "<<rate<<"!"
                <<"core_recovery_time "<<time<<"!"
           <<endl;
    local_core = &cores[core_id-1];

    local_core->core_id = core_id;
    local_core->task_scheduled = -1;
    local_core->task_sched_type = -1;
    local_core->rate = rate;
    local_core->scheduled_prio = PrioMin;
    local_core->ready_queue = init_task_list_head();
    local_core->suspend_queue = init_task_list_head();
    local_core->utilization = 0;
    local_core->isFailed = false;
    local_core->ceiling_prior=PrioMin;
    enqueue_utilization(local_core, core_utilization);
}


void initLocalCore(int core_id, double rate, int core_type)
{
    qDebug()<<"get "<<core_id<<"!"<<endl;
    qDebug()<<"core_id "<<core_id<<"!"
              <<"core_rate "<<rate<<"!"
                <<"core_recovery_time "<<time<<"!"
           <<endl;
    local_core = &cores[core_id-1];
    local_core->core_id = core_id;
    local_core->task_scheduled = -1;
    local_core->task_sched_type = -1;
    local_core->rate = rate;
    local_core->core_type=core_type;
    local_core->utilization = 0;
    local_core->ready_queue = init_task_list_head();
    local_core->ceiling_prior = PrioMin;
    enqueue_utilization(local_core, core_utilization);
}

void initCore(int core_id, double rate,int core_type)
{
    local_core = &cores[core_id-1];

    local_core->core_id = core_id;
    local_core->task_scheduled = -1;
    local_core->task_sched_type = -1;
    local_core->rate = rate;
    local_core->utilization = 0;
    local_core->isFailed = false;
    local_core->core_type=core_type;
    local_core->ready_queue = init_task_list_head();
    local_core->ceiling_prior = PrioMin;
    enqueue_utilization(local_core, core_utilization);
}


void queue_core_table(Core *core)
{
    struct core_table temp_table;
    int j,i;
    for (i = 0; i < core->table_length-1;i ++)//size-1是因为不用与自己比较，所以比的数就少一个
    {
        int count = 0;
        for (j = 0; j < core->table_length-1; j++)	//size-1-i是因为每一趟就会少一个数比较
        {
            if (core->table[j].start>core->table[j+1].start)//这是升序排法，前一个数和后一个数比较，如果前数大则与后一个数换位置
            {
                temp_table=core->table[j+1];
                core->table[j+1]=core->table[j];
                core->table[j]= temp_table;
                count = 1;

            }
        }
        if (count == 0)			//如果某一趟没有交换位置，则说明已经排好序，直接退出循环
                break;
    }


}


int get_corenum()
{
    int i;
    for(i=0;cores[i].core_id!=0;i++)
    {}
    return i;
}
